using Godot;
using System;
using System.Linq;
using System.Text.RegularExpressions;
public partial class Card : Sprite2D
{
	private Tween tween;
	private Tween.EaseType EaseType { get; set; } = Tween.EaseType.Out;
	private Tween.TransitionType TransitionType { get; set; } = Tween.TransitionType.Quad;
	private CollisionShape2D collisionShape;
	[Export]
	public int location { get; set; }
	[Export]
	public string id { get; set; }
	[Export]
	public string name { get; set; }
	[Export]
	public int atk { get; set; }
	[Export]
	public int def { get; set; }
	[Export]
	public int grade { get; set; }
	[Export]
	public string attribute { get; set; }

	public bool penetrate = false;
	public bool capacityDef = false;
	private string areaName;
	public int attackTimes = 0;

	public int extraAttackTimes = 0;
	[Signal]
	public delegate void UseCardSignalEventHandler(int value, Vector2 myPosition, Area2D a1);
	[Signal]
	public delegate void SelfDisappearSignalEventHandler(int location, Vector2 myPosition);
	[Signal]
	public delegate void SelectCardSignalEventHandler(int grade, Card p1, Card p2);
	[Export]
	public Sprite2D[] environmentsBlue { get; set; }
	private Timer _longPressTimer;
	private const float LONG_PRESS_DURATION = 1.5f;
	private bool longPress = false;
	private bool haveEntry = false;
	private bool haveSelected = false;
	private Area2D _targetNode;
	private Area2D _mergeNode;
	private Vector2 _startNodePosition = new Vector2(0, 0);
	private Vector2 _startMousePosition = new Vector2(0, 0);
	private Vector2 _newStartNodePosition = new Vector2(0, 0);
	private Sprite2D _bigSprite;
	private Player _playSprite;
	private Label label;
	public int status = 0;
	private bool isDelete = false;
	private bool twoTag = false;
	private Sprite2D g1;
	private Sprite2D g2;
	public override void _Ready()
	{
		tween = CreateTween();
		Name = id;
		Position = new Vector2(785, 0);
		Texture = GD.Load<Texture2D>("res://photo/card/low/" + name + ".png");
		tween.SetParallel(true);
		switch (location)
		{
			case 1:
				tween.TweenProperty(this, "position", new Vector2(-460, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 2:
				tween.TweenProperty(this, "position", new Vector2(-310, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 3:
				tween.TweenProperty(this, "position", new Vector2(-160, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 4:
				tween.TweenProperty(this, "position", new Vector2(-10, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 5:
				tween.TweenProperty(this, "position", new Vector2(140, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 6:
				tween.TweenProperty(this, "position", new Vector2(290, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 7:
				tween.TweenProperty(this, "position", new Vector2(440, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			case 8:
				tween.TweenProperty(this, "position", new Vector2(590, -160), 1.0f).SetTrans(TransitionType).SetEase(EaseType);
				break;
			default:
				break;
		}
		tween.TweenProperty(this, "scale", new Vector2(0.8f, 0.8f), 1.0f)
			  .SetTrans(TransitionType)
			  .SetEase(EaseType);
		tween.Play();

		_longPressTimer = new Timer();
		_longPressTimer.WaitTime = LONG_PRESS_DURATION;
		_longPressTimer.OneShot = true;
		_longPressTimer.Timeout += OnLongPressTimeout;
		AddChild(_longPressTimer);

		Area2D area = new Area2D();
		collisionShape = new CollisionShape2D();
		RectangleShape2D rectangleShape = new RectangleShape2D();
		rectangleShape.Size = Texture.GetSize() * Scale;
		collisionShape.Shape = rectangleShape;
		area.AddChild(collisionShape);
		area.MouseEntered += OnBodyEntered;
		area.MouseExited += OnBodyExited;
		area.AreaEntered += OnAreaEntered;
		area.AreaExited += OnAreaExited;
		AddChild(area);

		label = new Label();
		label.Text = "攻:" + atk + "\n守:" + def;
		label.Position = new Vector2(-50, 30);
		label.AddThemeColorOverride("font_color", Colors.Green);
		label.AddThemeFontSizeOverride("font_size", 26);
		label.Visible = false;
		AddChild(label);

		_bigSprite = GetParent().GetParent().GetNode<Sprite2D>("BigTemplate");
		_playSprite = GetParent().GetParent().GetNode<Player>("Player");

		g1 = GetParent().GetParent().GetNode<Sprite2D>("垃圾");
		g2 = g1.GetNode<Sprite2D>("垃圾2");
	}
	public override void _ExitTree()
	{
		base._ExitTree();
	}
	public void changeAD(int a, int d)
	{
		this.atk = a;
		this.def = d;
		label.Text = "攻:" + this.atk + "\n守:" + this.def;
	}
	public void OnAreaEntered(Area2D node)
	{
		if (node.IsInGroup("empty") && _targetNode == null && status == 0)
		{
			_newStartNodePosition = node.GetChildren().OfType<CollisionShape2D>().FirstOrDefault().GlobalPosition;
			node.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "待选位置").Visible = false;
			node.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "选中位置").Visible = true;
			_targetNode = node;
		}
		if (node.IsInGroup("trashCan") && status == 2)
		{
			g2.Visible = true;
			isDelete = true;
		}
		if (node.IsInGroup("full") && haveSelected && areaName != node.Name)
		{
			_mergeNode = node;
			twoTag = true;
		}
	}
	public void OnAreaExited(Area2D node)
	{
		if (node.IsInGroup("empty") && _targetNode == node && status == 0)
		{
			_newStartNodePosition = new Vector2(0, 0);
			node.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "待选位置").Visible = true;
			node.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "选中位置").Visible = false;
			_targetNode = null;
		}
		if (node.IsInGroup("trashCan") && status == 2)
		{
			g2.Visible = false;
			isDelete = false;
		}
		if (node.IsInGroup("full") && _mergeNode == node && haveSelected && areaName != node.Name)
		{
			_mergeNode = null;
			twoTag = false;
		}
	}
	public void OnBodyEntered()
	{
		haveEntry = true;
		_longPressTimer.Start();
	}
	public void OnBodyExited()
	{
		haveEntry = false;
		_longPressTimer.Stop();
		_bigSprite.Visible = false;
	}
	public override void _Process(double delta)
	{
		if (longPress)
		{
			Position = _startNodePosition + (GetGlobalMousePosition() - _startMousePosition);
		}
		var num = environmentsBlue.Count(n => n.Visible);
		if (num != 0 && num != 5)
		{
			for (int i = 0; i < 5; i++)
			{
				environmentsBlue[i].Visible = false;
			}
		}
	}

	public override void _Input(InputEvent @event)
	{
		if (status == 0)
		{
			if (@event is InputEventMouseButton mouseEvent &&
			mouseEvent.ButtonIndex == MouseButton.Left)
			{
				if (mouseEvent.Pressed)
				{
					if (haveEntry)
					{
						if (_startMousePosition.X == 0 && _startMousePosition.Y == 0)
						{
							_startMousePosition = GetGlobalMousePosition();
						}
						if (_startNodePosition.X == 0 && _startNodePosition.Y == 0)
						{
							Scale = Scale * 1.2f;
							_startNodePosition = Position;
							for (int i = 0; i < 5; i++)
							{
								environmentsBlue[i].Visible = true;
							}
							longPress = true;
						}
					}
				}
				else
				{
					if (longPress)
					{
						longPress = false;
						if (haveSelected)
						{
							if (!twoTag)
							{
								Position = _startNodePosition;
								Scale = Scale / 1.2f;
							}
							else
							{
								Match match = Regex.Match(_mergeNode.Name, @"\d+$");
								if (match.Success)
								{
									int number = int.Parse(match.Value);

									if (_playSprite.upCards[number - 6].grade + grade == 2 || _playSprite.upCards[number - 6].grade + grade == 4 || _playSprite.upCards[number - 6].grade + grade == 6 || _playSprite.upCards[number - 6].grade + grade == 8 || _playSprite.upCards[number - 6].grade + grade == 10)
									{
										if (_playSprite.energyUseing >= _playSprite.upCards[number - 6].grade + grade)
										{
											EmitSignal(SignalName.SelectCardSignal, _playSprite.upCards[number - 6].grade + grade, this, _playSprite.upCards[number - 6]);
										}
										else
										{
											Position = _startNodePosition;
											Scale = Scale / 1.2f;
											_mergeNode = null;
											twoTag = false;
										}
									}
									else
									{
										Position = _startNodePosition;
										Scale = Scale / 1.2f;
										_mergeNode = null;
										twoTag = false;
									}


								}
							}

						}
						else
						{
							if (haveSelected || _newStartNodePosition.X == 0 && _newStartNodePosition.Y == 0)
							{
								Position = _startNodePosition;
								Scale = Scale / 1.2f;
							}
							else
							{
								moveUpCard(grade, _targetNode, _newStartNodePosition, _startNodePosition, location, Name, grade <= _playSprite.energyUseing);
							}

						}
						for (int i = 0; i < 5; i++)
						{
							environmentsBlue[i].Visible = false;
						}
						_startMousePosition = new Vector2(0, 0);
						_newStartNodePosition = new Vector2(0, 0);
						_startNodePosition = new Vector2(0, 0);
					}
				}
			}
		}
		else if (status == 2)
		{
			if (@event is InputEventMouseButton mouseEvent &&
		mouseEvent.ButtonIndex == MouseButton.Left)
			{
				if (mouseEvent.Pressed)
				{
					if (haveEntry)
					{
						if (_startMousePosition.X == 0 && _startMousePosition.Y == 0)
						{
							_startMousePosition = GetGlobalMousePosition();
						}
						if (_startNodePosition.X == 0 && _startNodePosition.Y == 0)
						{
							Scale = Scale * 1.2f;
							_startNodePosition = Position;
							longPress = true;
							g1.Visible = true;
						}
					}
				}
				else
				{
					if (longPress)
					{
						g1.Visible = false;
						longPress = false;
						if (haveSelected || !isDelete)
						{
							Position = _startNodePosition;
							Scale = Scale / 1.2f;
						}
						else
						{
							EmitSignal(SignalName.SelfDisappearSignal, location, _startNodePosition);
						}
						_startMousePosition = new Vector2(0, 0);
						_newStartNodePosition = new Vector2(0, 0);
						_startNodePosition = new Vector2(0, 0);
					}
				}
			}
		}
		else
		{

		}

	}

	private void moveUpCard(int grade, Area2D a1, Vector2 a2, Vector2 a3, int a4, string a5, bool tag)
	{
		if (Name == a5)
		{
			if (tag)
			{
				a1.RemoveFromGroup("empty");
				a1.AddToGroup("full");
				a1.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "待选位置").Visible = false;
				a1.GetChildren().OfType<Sprite2D>().FirstOrDefault(child => child.Name == "选中位置").Visible = false;
				areaName = a1.Name;
				GlobalPosition = a2;
				haveSelected = true;
				label.Visible = true;
				AddToGroup("up");
				EmitSignal(SignalName.UseCardSignal, a4, a3, a1);
			}
			else
			{
				Position = a3;
				Scale = Scale / 1.2f;
			}
		}
	}
	private void OnLongPressTimeout()
	{
		if (!longPress)
		{
			_bigSprite.Texture = GD.Load<Texture2D>("res://photo/card/high/" + name + ".png");
			_bigSprite.Visible = true;

		}


	}

}
